use actix_web::{get, middleware, post, web, App, Error, HttpResponse, HttpServer};
use diesel::prelude::*;
use diesel::r2d2::{self, ConnectionManager};
use uuid::Uuid;
use crate::todo::actions;
use crate::todo::models;
/// Finds todo by UID.
type DbPool = r2d2::Pool<ConnectionManager<SqliteConnection>>;

#[get("/rest/todo/{user_id}")]
async fn get_todo(
    pool: web::Data<DbPool>,
    user_uid: web::Path<i32>,
) -> Result<HttpResponse, Error> {
    let conn = pool.get().expect("couldn't get db connection from pool");

    // use web::block to offload blocking Diesel code without blocking server thread
    let todo = web::block(move || actions::find_user_by_uid(user_uid.into_inner(), &conn))
        .await
        .map_err(|e| {
            eprintln!("{}", e);
            HttpResponse::InternalServerError().finish()
        })?;

    if let Some(todo) = todo {
        Ok(HttpResponse::Ok().json(todo))
    } else {
        let res = HttpResponse::NotFound()
            .body(format!("No todo found with uid: "));
        Ok(res)
    }
}

/// Inserts new todo with name defined in form.
#[post("/rest/todo")]
async fn add_todo(
    pool: web::Data<DbPool>,
    form: web::Json<models::Todo>,
) -> Result<HttpResponse, Error> {
    let conn = pool.get().expect("couldn't get db connection from pool");

    // use web::block to offload blocking Diesel code without blocking server thread
    let todo = web::block(move || actions::insert_new_user(&form.text, &conn))
        .await
        .map_err(|e| {
            eprintln!("{}", e);
            HttpResponse::InternalServerError().finish()
        })?;

    Ok(HttpResponse::Ok().json(todo))
}

// function that will be called on new Application to configure routes for this module
pub fn init(cfg: &mut web::ServiceConfig) {
    cfg.service(add_todo);
    cfg.service(get_todo);
    // info!("after init");
}
